<!-- 滚动加载和下拉刷新组件, 案例message/idnex.vue -->
<template>
	<view class="scrollViewBody" :style="'height: calc(100% - ' + minusHeight + 'px);'">
		<movable-area class="movableBox">
			<movable-view
        class="movableView"
				:style="'height:calc(100% + ' + (noTop ? 0 : topHeight) + 'px);'"
				direction="vertical"
				:out-of-bounds="true"
				:disabled="pageDisabled"
				:y="y"
				:damping="50"
				@touchstart="touchstart"
				@touchend="touchend"
				@change="change"
			>
				<!-- 解决回弹后偏差 -->
				<view :style="'height:' + topHeight + 'px;position:relative;'" v-if="!noTop">
          <image
              src="../../static/image/loading.gif"
              mode="heightFix"
              :style="'position: absolute;bottom: 0px;left:calc(50% - 20px);height: ' + interruptPosition + 'px;line-height:' + interruptPosition + 'px;width: auto;'"
          />
        </view>
				<scroll-view
          :scroll-y="refreshStatus!== 3&&scrollY"
          :scroll-with-animation="scrollAnimation"
          :scroll-top="scrollTop"
          :class="{'is_fixed':isFixed}"
          :style="'height: calc(100% - ' + (noTop ? 0 : topHeight) + 'px);'"
          @scroll="scroll"
          @scrolltolower="scrolltolower"
        >
					<slot name="content"></slot>
					<template>
						<view :style="'height: 40px;line-height: 40px;width: 100%;text-align: center;color:#969799;'" v-if="loadStatus !== 3">
							<image
                  mode="heightFix" src="../../static/image/loading.gif"
                  :class="loadStatus === 2 ? 'animated' : (loadStatus === 1 ? 'op1' : 'op0')"
                  :style="'height: ' + interruptPosition + 'px;line-height:' + interruptPosition + 'px;width: auto;transition: opacity 2s'"
              />
						</view>
						<view style="height: 15px;" v-else></view>
					</template>
				</scroll-view>
			</movable-view>
		</movable-area>
	</view>
</template>

<script>
// // 子组件方法
// // 下拉刷新方法，刷新完毕调用组件方法改变状态
// interrupt() {
//   setTimeout(() => {
//     this.$refs.scrollView.refreshFinish() // 刷新完成
//   }, 1000);
// },
// // 底部加载更多
// scrolltolower(e){
//   setTimeout(() => {
//     this.$refs.scrollView.loadFinish(0 || 3) // 加载完成
//   }, 1000);
// }
export default {
	props: {
		minusHeight: {
			// 主盒子需要减去的高度
			type: Number,
			default: 0
		},
    scrollY: { // 允许纵向滚动，配合refreshStatus!==3使用才能滚动
      type: Boolean,
      default: true
    },
		topHeight: {
			//下拉区的高度(px)
			type: Number,
			default: 60
		},
		interruptPosition: {
			//暂停区的高度(px)
			type: Number,
			default: 40
		},
		// 是否禁用下拉刷新
		noTop:{
			type: Boolean,
			default: false
		},
    // 是否使用fixed--此参数用于有子元素定位使用了sticky
    isFixed: {
      type: Boolean,
      default: false
    },
    // 指定到滚动位置时是否使用过渡动画
    scrollAnimation: {
      type: Boolean,
      default: true
    }
	},
	computed:{
		// 是否禁止滚动 滚动到顶部时，刷新时，加载时 禁用
		pageDisabled(){
			if(!this.scrollmark || this.refreshStatus == 3 || this.loadStatus == 1){
				return true
			}else{
				return false
			}
		}
	},
	data() {
		return {
			isTouch: false,//触摸的标识
			y: 0,//控制y
			diff: 0,//定值topHeight-interruptPotion
			scrollmark: true,
			timeId: null,
			// count: 0.01,
		  refreshStatus: 0, // 0是可以加载更多
      loadStatus: 0, // 0 是可以加载更多  1是加载中  2加载完成  3无更多可加载
      scrollTop: 0, // 滚动的位置记录
      old: {
        scrollTop: 0,
				movableScroll: 0
      },
		};
	},
	created() {
		this.y = -this.topHeight;
		this.diff = this.interruptPosition - this.topHeight;
	},
  methods: {
		// 开始触摸
		touchstart(e) {
			if (this.refreshStatus == 3 || this.noTop) {
				return
			}
			this.isTouch = true;
		},
		// 结束触摸
		touchend(e) {
			console.log(this.refreshStatus,'ljx',this.scrollmark);
			if (this.refreshStatus == 3 || this.noTop) return
			this.isTouch = false;
			if (this.scrollmark) {
				if (this.refreshStatus == 2) {
					this.refreshStatus = 3;
					this.y = this.diff;

					this.$emit('interrupt'); // 刷新，执行刷新方法
				} else if (this.refreshStatus == 1) {
					this.refreshFinish()
				}else{
					console.log('异常直接回归');
					this.refreshFinish()
				}
			}
		},
		// 回弹区高度变化
		change(e) {
			//为3即是正在回弹状态
			if (this.refreshStatus == 3 || !this.isTouch) return;
			if (e.detail.y >= this.diff) { // 开始刷新
				this.refreshStatus = 2;
			} else if (e.detail.y < this.diff) {
				this.refreshStatus = 1;
			}
		},
    // 刷新完成
    refreshFinish(){
      this.y = -this.topHeight;
			this.loadStatus = 0 // 加载更多回归初始状态
      setTimeout(() => {
        this.refreshStatus = 0; //回弹过程中
				this.y = -60.01 // 此处解决回弹不了的bug,Y设置成功，style却不变，官方bug
      }, 1000);
    },
    // 滚动事件
		scroll(e) {
      this.old.scrollTop = e.detail.scrollTop
			this.$emit('scroll',e)
			this.scrollmark = false;
      if (this.timeId) clearTimeout(this.timeId)
			this.timeId = setTimeout(() => {
				if (e.detail.scrollTop <= 15 || e.detail.scrollTop - e.detail.deltaY <= 0) {
					this.$emit('scrolltoupper',e)  // 原有滚到顶部方法
					this.scrollmark = true;
				}
			}, 500);
		},
    // 原有滚到底部方法
		scrolltolower(e){
      if(this.loadStatus == 0){ // 可加载更多
        this.loadStatus = 1 // 加载中
			  this.$emit('scrolltolower',e);
      }
		},
    // 加载完成  toggleTime 切换状态时间，解决切换时bug
    loadFinish(status,toggleTime = 800){
      this.loadStatus = 2 // 加载完毕
      // 判断是否还可加载
      setTimeout(() => {
        this.loadStatus = status // 可加载更多过无更多可加载
      }, toggleTime);
    },
    // 滚动到指定位置--在子组件中调用
    goToScroll(scrollTop) {
      this.scrollTop = this.old.scrollTop
      this.$nextTick(() => {
        this.scrollTop = scrollTop || 0
      })
    }
	}
};
</script>
<style lang="scss" scoped>
.scrollViewBody{
  width:100%;
  .movableBox{
    width:100%;
    height: 100%;
    overflow: hidden;
    .movableView{
      width:100%;
      z-index:3;
    }
		.movableView.scolly{
			transform: translateX(0px) translateY(-60px) translateZ(0px) scale(1) !important;
		}
  }
}
.is_fixed {
    position: fixed;
    left: 0;
    bottom: 0;
    right: 0;
    width: auto;
    z-index: 3;
}
.op1{
	opacity: 1;
}
.op0{
	opacity: 0;
}
.animated{
  animation: twinkling 2s;
}
@keyframes twinkling{
  0%{
    opacity: 1;
  }
  100%{
    opacity: 0;
  }
}
</style>
